package com.cskaoyan.object01.syntax.keystatic;

/*
     static关键字：可以修饰成员变量和成员方法
         被static修饰成员变量，称之为静态成员变量，简称静态变量
         被static修饰的成员方法，称之为静态成员方法，简称静态方法


     1. 被当前类的所有 对象所共享(共享特征)：（判定是否使用static的关键, 这里就说明static的使用场景)
        a. 当static修饰了成员变量，该成员变量的值，就不在存储于对象中了，
            而是，单独存储了一份，被类的所有对象所共享

        b.  当static修饰成员方法的时候，该方法被当前类的所有对象共享
            当前类对象.方法（和普通成员方法从共享的角度，几乎没有太大区别）

    2. 可以通过类名访问（对于静态成员，官方推荐类名.访问静态成员）
        a. 可以通过类名直接访问，static成员变量的值
        b. 直接通过类名直接调用，static成员方法

  3. 随着类的加载而加载(出现在内存中的时间)
      a. static成员变量，随着类加载过程，其实就已经在方法区中，分配了内存，并赋予默认初值
      b. static成员方法, 一旦类加载完毕，我们就可以直接访问，static方法(通过类名.)，而不必等待创建该类对象

  4. 优先于对象而存在(不依赖于对象而存在)

      a. 静态变量
          1）成员变量的角度来理解，static修饰的成员变量，不在依赖于对象而存在，因为static修饰的成员变量的值，
            不在存储在，该类的每个对象中
          2）作为对比，没有被static修饰的成员变量，都依赖于对象而存在，因为他们的值，都存储在对象中

      b. 静态方法
          1）成员方法角度，被static修饰的成员方法，在没有对象存在的情况下，也可以直接通过类名来调用方法
          2）作为对比，没有被static修饰的，普通成员方法，它依赖于对象而存在


      static关键字的注意事项:
         1. 在静态上下文中(比如静态方法中)，不能访问非静态的成员变量或者非静态的成员方法
            a. 这里，实际上不能访问的是 当前对象 的非静态成员变量和非静态成员方法
            b. 如果我们是在自己创建出的已经存在的对象上访问非静态的成员变量和成员方法是可以的

         2. static方法体中不能使用static关键字

         3. 静态变量和静态方法的使用场景
           a. 如果我们希望一个成员变量，能够被该类的所有对象所共享，该变量可以定义
              static 静态变量
           b. 如果说一个方法，该方法作为一个工具方法实现，为了放便调用，我们可以把这种
              被频繁调用工具方法，定义static 方法

 */
public class Demo2Static {

    public static void main(String[] args) {

        // 被static修饰的成员 类名.的方式访问
//        System.out.println(StaticClass.a);
//        StaticClass.staticMethod();

        // 被static修饰成员变量和成员方法，对象.方式访问
//        StaticClass obj = new StaticClass();
//        System.out.println(obj.a);
//        obj.staticMethod();

        // 随着类加载而加载
        // 不创建任何对象，直接通过类名来访问
        //StaticClass.a = 1000;
        //System.out.println(StaticClass.a);
        // 在来加载完就可以访问了
        //StaticClass.staticMethod();

        // 不依赖与对象而存在
        //StaticClass staticClass = new StaticClass();
        // 普通成员方法
        //staticClass.memberMethod();

        // 静态方法
        StaticClass.staticMethod();
    }
}


class StaticClass {
    // 静态成员变量
    static int a;

    // 普通成员变量
    double b;

    public static void staticMethod() {
        // 静态方法中，访问非静态的成员变量
        //System.out.println(this.b);

        // 静态方法中，访问非静态的成员方法
        //this.memberMethod();

//        // 自己创建出的对象上
        StaticClass obj = new StaticClass();
        // 非静态的成员变量
        System.out.println(obj.b);

        // 非静态的成员方法
        obj.memberMethod();


        System.out.println("staticMethod");

        // 在方法体中定义不能使用static
         //static int value;
    }

    public void memberMethod() {
        // 普通成员变量值
        System.out.println(this.b);
        System.out.println("memberMethod");


        //static int a;

        // 可以访问静态变量和静态方法
        System.out.println(a);
        staticMethod();
    }
}
